# Copyright (c) 2020 Presto Labs Pte. Ltd.
# Author: jingyuan

import datetime
import os
import time
import subprocess
import traceback

from absl import (flags, app)

from xunkemgmt_client.tool.slack_noti import send_to_slack


FLAGS = flags.FLAGS


def report_slack(log_file, lines=20, user="jingyuan"):
  channel = 'coin_ops_monitor'
  mention_list = user.split(',') if user else None
  dt = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
  msgs = [
      '```',
      f'strategy_group: {FLAGS.strategy_group}, trader: {user} ({dt})',
      f'    {FLAGS.strategy_name}: unexpected restart', '```']
  send_to_slack('\n'.join(msgs), channel, 'msg', mention_list=mention_list)
  logs = subprocess.run(["tail", "-n", str(lines), log_file], capture_output=True)
  send_to_slack(logs.stdout.decode(), channel, 'file', mention_list=mention_list)


def get_trading_date(trading_date):
  trading_date_int = int(trading_date)
  if abs(trading_date_int) <= 10:
    date = datetime.datetime.now() + datetime.timedelta(days=trading_date_int)
    trading_date = date.strftime('%Y%m%d')
  elif len(trading_date) != 8:
    raise ValueError(f'Wrong trading_date format {trading_date}')
  return trading_date


def main(argv):
  strategy_group = FLAGS.strategy_group
  strategy_name = FLAGS.strategy_name
  driver = FLAGS.driver
  config = FLAGS.config
  assert strategy_group
  # assert strategy_name
  assert driver
  assert config
  is_sim = FLAGS.is_sim
  trading_date = FLAGS.trading_date
  if is_sim:
    assert trading_date
    trading_date = get_trading_date(trading_date)

  if strategy_group == 'basis_exchange':
    binary = 'bazel-bin/cc/appcoin2/strategy/basis_exchange/live_runner'
  else:
    raise NotImplementedError(f'{strategy_group} not exists.')

  # tmp_dir = f'{strategy_group}_tmp'
  # if not os.path.exists(tmp_dir):
  #   os.makedirs(tmp_dir)

  # tmp_driver_file = tempfile.mkstemp(
  #     dir=tmp_dir,
  #     prefix=f'drive_{strategy_name}_',
  #     suffix='.json')[-1]

  # cmds = [
  #     './pyrunner',
  #     'cc/appcoin2/strategy/basis_strat/support/config_gen.py',
  #     f'--config_path={driver}',
  #     f'--is_sim={is_sim}',
  #     f'--trading_date={trading_date}',
  #     f'--output_path={tmp_driver_file}']

  # cmd = ' '.join(cmds)
  # print(cmd)
  # ret = os.system(cmd)
  # if ret != 0:
  #   print('Config gen failed.')
  #   return 1

  # assert os.path.exists(tmp_driver_file)

  log_dir = f'log_{strategy_name}'
  log_path = os.path.join(log_dir, strategy_name)
  if not os.path.exists(log_dir):
    os.makedirs(log_dir)
  elif os.path.exists(log_path):
    tmp_log_path = f'{log_path}_tmp'
    os.system(f'tail -1000000 {log_path} > {tmp_log_path} && mv {tmp_log_path} {log_path}')

  extra_flags = []
  if FLAGS.other_flags:
    for key_val in FLAGS.other_flags.split(','):
      extra_flags.append(f'--{key_val}')
  extra_flags = ' '.join(extra_flags)

  cmd = f'GLOG_logtostderr=1 {binary} --driver={driver} --config={config} {extra_flags} >> {log_path} 2>&1'
  print(cmd)
  last_slack_ts = 0
  while True:
    os.system(cmd)
    if is_sim:
      break
    try:
      ts = time.time()
      if ts - last_slack_ts > 120:
        last_slack_ts = ts
        report_slack(log_path)
    except Exception as e:
      traceback.print_exc()
    time.sleep(2)


if __name__ == '__main__':
  flags.DEFINE_string('strategy_name', '', '')
  flags.DEFINE_string('strategy_group', '', '')
  flags.DEFINE_string('driver', '', 'Drive related configs.')
  flags.DEFINE_string('config', '', 'Strategy related configs.')
  flags.DEFINE_boolean('is_sim', False, '')
  flags.DEFINE_string('trading_date', '', 'For sim use only.')
  flags.DEFINE_string('other_flags', '', 'key=value separted by comma.')
  app.run(main)
